package com.cwj.thread;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author chenwujie
 * @date 2021-03-02 15:45
 */
public class FizzBuzz {
    private int n;
    private AtomicInteger[] arr;

    public FizzBuzz(int n) {
        this.n = n;
        this.arr = new AtomicInteger[n];
        for(int i = 0; i < arr.length; i++){
            arr[i] = new AtomicInteger(3);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        FizzBuzz fizzBuzz = new FizzBuzz(15);
        Runnable r1 = new Runnable() {
            @Override
            public void run() {
                for(int i = 0; i < fizzBuzz.n; i++){
                    boolean zc = (i + 1) % 3 == 0;
                    for(;;){
                        int e = fizzBuzz.arr[i].get();
                        int u = zc ? (e | 4) & 0b1110 : e & 0b1010;
                        if(fizzBuzz.arr[i].compareAndSet(e, u)){
                            break;
                        }
                    }
                    for(;;){
                        int e = fizzBuzz.arr[i].get();
                        if((e & 2) == 0){
                            if(e == 4){
                                System.out.println( i + 1 + "fizz");
                            }
                            break;
                        }
                    }

                }
            }
        };
        Runnable r2 = new Runnable() {
            @Override
            public void run() {
                for(int i = 0; i < fizzBuzz.n; i++){
                    boolean zc = (i + 1) % 5 == 0;
                    for(;;){
                        int e = fizzBuzz.arr[i].get();
                        int u = zc ? (e | 8) & 0b1101 : e & 0b0101;
                        if(fizzBuzz.arr[i].compareAndSet(e, u)){
                            break;
                        }
                    }
                    for(;;){
                        int e = fizzBuzz.arr[i].get();
                        if((e & 2) == 0){
                            if(e == 8){
                                System.out.println( i + 1 + "buzz");
                            }
                            break;
                        }
                    }
                }
            }
        };
        Runnable r3 = new Runnable() {
            @Override
            public void run() {
                for(int i = 0; i < fizzBuzz.n; i++){
                    for(;;){
                        int e = fizzBuzz.arr[i].get();
                        if((e & 2) == 0){
                            if(e == 12){
                                System.out.println( i + 1 + "fizzbuzz");
                            }
                            break;
                        }
                    }
                }
            }
        };
        Runnable r4 = new Runnable() {
            @Override
            public void run() {
                for(int i = 0; i < fizzBuzz.n; i++){
                    for(;;){
                        int e = fizzBuzz.arr[i].get();
                        if((e & 2) == 0){
                            if(e == 0){
                                System.out.println( i + 1 );
                            }
                            break;
                        }
                    }
                }
            }
        };

        Thread thread1 = new Thread(r1, "t1");
        Thread thread2 = new Thread(r2, "t2");
        Thread thread3 = new Thread(r3, "t3");
        Thread thread4 = new Thread(r4, "t4");

        thread1.start();
        thread2.start();
        thread3.start();
        thread4.start();

        thread1.join();
        thread2.join();
        thread3.join();
        thread4.join();

    }

}
